home *** CD-ROM | disk | FTP | other *** search
- /****************************************************************************
- *
- * OSLHelpers.c
- *
- ****************************************************************************/
-
- #include <string.h> // for strncmp()
- #include <stdio.h> // for sprintf()
-
- #include "OSLHelpers.h"
-
- #include "Sounds.h"
- #include "StringUtils.h"
-
- #include "AERCoreSuite.h"
-
- #include "DocumentADT.h"
- #include "DocumentHelpers.h"
-
- #include "WindowUtils.h"
-
- #include "ElementADT.h"
- #include "ElementHelpers.h"
-
- #include "Assertion.h"
-
- #include "OSLClassGraphicObject.h"
- #include "OSLClassWindow.h"
- #include "OSLClassDocument.h"
-
- // --------------------------------------------------------------------------
- // file globals
-
-
- static ColorRecord fgColorTable[] =
- {
- {"Black", eBlack, kRGBBlack },
- {"White", eWhite, kRGBWhite },
-
- {"Red", eRed, kRGBRed },
- {"Blue", eBlue, kRGBBlue },
- {"Green", eGreen, kRGBGreen },
-
- {"Cyan", eCyan, kRGBCyan },
- {"Magenta", eMagenta, kRGBMagenta },
- {"Yellow", eYellow, kRGBYellow },
-
- {"Olive", eOlive, kRGBOlive },
- {"Purple", ePurple, kRGBPurple },
- {"Orange", eOrange, kRGBOrange },
- {"Brown", eBrown, kRGBBrown },
-
- {"Gray 1", eGray01, kRGBGray01 },
- {"Gray 2", eGray02, kRGBGray02 },
- {"Gray 3", eGray03, kRGBGray03 },
- {"Gray 4", eGray04, kRGBGray04 },
- {"Gray 5", eGray05, kRGBGray05 },
- {"Gray 6", eGray06, kRGBGray06 },
- {"Gray 7", eGray07, kRGBGray07 },
- {"Gray 8", eGray08, kRGBGray08 },
- {"Gray 9", eGray09, kRGBGray09 },
- {"Gray 10", eGray10, kRGBGray10 },
- {"Gray 11", eGray11, kRGBGray11 },
- {"Gray 12", eGray12, kRGBGray12 },
- {"Gray 13", eGray13, kRGBGray13 },
- {"Gray 14", eGray14, kRGBGray14 },
- {"Gray 15", eGray15, kRGBGray15 },
- {"Gray 16", eGray16, kRGBGray16 },
- };
-
- static short fgNumColors = sizeof(fgColorTable) / sizeof(ColorRecord);
-
- // ----------------------------------------------------------------------------------------
- // Object callback functions
- // ----------------------------------------------------------------------------------------
-
- static pascal OSErr
- OSLCountObjectsCallback (DescType desiredType,
- DescType containerClass,
- const AEDesc *container,
- long *result);
-
- static pascal OSErr
- OSLCompareObjectsCallback (DescType comparisonOperator,
- const AEDesc *object,
- const AEDesc *descriptorOrObject,
- Boolean *result);
-
- // ----------------------------------------------------------------------------------------
- // Comparison functions used by OSLCompareObjectsCallback()
- // ----------------------------------------------------------------------------------------
-
- static OSErr
- OSLCompareText (DescType oper,
- const AEDesc *desc1,
- const AEDesc *desc2,
- Boolean *result);
-
- static OSErr
- OSLCompareEnumeration (DescType oper,
- const AEDesc *desc1,
- const AEDesc *desc2,
- Boolean *result);
-
- static OSErr
- OSLCompareInteger (DescType oper,
- const AEDesc *desc1,
- const AEDesc *desc2,
- Boolean *result);
-
- static OSErr
- OSLCompareFixed (DescType oper,
- const AEDesc *desc1,
- const AEDesc *desc2,
- Boolean *result);
-
- static OSErr
- OSLCompareFloat (DescType oper,
- const AEDesc *desc1,
- const AEDesc *desc2,
- Boolean *result);
-
- static OSErr
- OSLCompareBoolean (DescType oper,
- const AEDesc *desc1,
- const AEDesc *desc2,
- Boolean *result);
-
- static OSErr
- OSLCompareRGBColor (DescType oper,
- const AEDesc *desc1,
- const AEDesc *desc2,
- Boolean *result);
-
- static OSErr
- OSLComparePoint (DescType oper,
- const AEDesc *desc1,
- const AEDesc *desc2,
- Boolean *result);
-
- static OSErr
- OSLCompareRect (DescType oper,
- const AEDesc *desc1,
- const AEDesc *desc2,
- Boolean *result);
-
- // ----------------------------------------------------------------------------------------
- // Coercion Handlers
- // ----------------------------------------------------------------------------------------
-
- static pascal OSErr
- CoerceColorNameToRGBColor(
- const AEDesc *fromDesc,
- DescType toType,
- long handlerRefCon,
- AEDesc *result);
-
- static pascal OSErr
- CoerceColorCodeToRGBColor(
- const AEDesc *fromDesc,
- DescType toType,
- long handlerRefCon,
- AEDesc *result);
-
- static pascal OSErr
- CoerceRGBColorToColorName(
- const AEDesc *fromDesc,
- DescType toType,
- long handlerRefCon,
- AEDesc *result);
-
- static pascal OSErr
- CoerceTypeToEnumeration(
- const AEDesc *fromDesc,
- DescType toType,
- long handlerRefCon,
- AEDesc *result);
-
- static pascal OSErr
- CoerceEnumerationToType(
- const AEDesc *fromDesc,
- DescType toType,
- long handlerRefCon,
- AEDesc *result);
-
- //----------------------------------------------------------------------------------
- // Converts descriptor dataHandle to a DescType
- //----------------------------------------------------------------------------------
-
- OSErr
- DescToDescType(const AEDesc *desc, DescType *descType)
- {
- OSErr error = noErr;
-
- if (GetHandleSize(desc->dataHandle) == 4)
- *descType = *(DescType*)*(desc->dataHandle);
- else
- error = errAECoercionFail;
-
- return error;
- }
-
- //----------------------------------------------------------------------------------
- // Converts descriptor dataHandle to a boolean
- //----------------------------------------------------------------------------------
-
- OSErr
- DescToBoolean(const AEDesc* desc, Boolean* aBoolean)
- {
- AEDesc tempDesc = {typeNull, nil};
- Handle dataHandle = nil;
-
- if (desc->descriptorType == typeBoolean)
- {
- dataHandle = desc->dataHandle;
- }
- else
- {
- if (AECoerceDesc(desc, typeBoolean, &tempDesc) == noErr)
- dataHandle = tempDesc.dataHandle;
- else
- return errAECoercionFail;
- }
-
- *aBoolean = **dataHandle;
-
- AEDisposeDesc(&tempDesc);
-
- return(noErr);
- }
-
- //----------------------------------------------------------------------------------
- // Converts descriptor dataHandle to a Fixed
- //----------------------------------------------------------------------------------
-
- OSErr
- DescToFixed(const AEDesc* desc, Fixed* aFixed)
- {
- AEDesc tempDesc = {typeNull, nil};
- Handle dataHandle = nil;
-
- if (desc->descriptorType == typeFixed)
- {
- dataHandle = desc->dataHandle;
- }
- else
- {
- if (AECoerceDesc(desc, typeFixed, &tempDesc) == noErr)
- dataHandle = tempDesc.dataHandle;
- else
- return errAECoercionFail;
- }
-
- *aFixed = *(Fixed *)*dataHandle;
-
- AEDisposeDesc(&tempDesc);
-
- return(noErr);
- }
-
- //----------------------------------------------------------------------------------
- // Converts descriptor dataHandle to a float
- //----------------------------------------------------------------------------------
-
- OSErr
- DescToFloat(const AEDesc* desc, float* aFloat)
- {
- AEDesc tempDesc = {typeNull, nil};
- Handle dataHandle = nil;
-
- if (desc->descriptorType == typeFloat)
- {
- dataHandle = desc->dataHandle;
- }
- else
- {
- if (AECoerceDesc(desc, typeFloat, &tempDesc) == noErr)
- dataHandle = tempDesc.dataHandle;
- else
- return errAECoercionFail;
- }
-
- *aFloat = **(float**)dataHandle;
-
- AEDisposeDesc(&tempDesc);
-
- return(noErr);
- }
-
- //----------------------------------------------------------------------------------
- // Converts descriptor dataHandle to a long
- //----------------------------------------------------------------------------------
-
- OSErr
- DescToLong(const AEDesc* desc, long* aLong)
- {
- AEDesc tempDesc = {typeNull, nil};
- Handle dataHandle = nil;
-
- if (desc->descriptorType == typeLongInteger)
- {
- dataHandle = desc->dataHandle;
- }
- else
- {
- if (AECoerceDesc(desc, typeLongInteger, &tempDesc) == noErr)
- dataHandle = tempDesc.dataHandle;
- else
- return errAECoercionFail;
- }
-
- *aLong = *(long *)*dataHandle;
-
- AEDisposeDesc(&tempDesc);
-
- return(noErr);
- }
-
- //----------------------------------------------------------------------------------
- // gets two shorts out of a AEDesc which is an OSA Range Descriptor record
- // for an Error range.
- //----------------------------------------------------------------------------------
-
- OSErr
- DescToOSARange(const AEDesc *desc, short *start, short *end)
- {
- OSErr error = noErr;
- AEDesc tempDesc = {typeNull, NULL};
-
- Size actualSize;
- DescType actualType;
-
- *start = 0;
- *end = 0;
-
- error = AECoerceDesc(desc, typeAERecord, &tempDesc);
- if (error != noErr)
- {
- error = errAECoercionFail;
- goto CleanUp;
- }
-
- error = AEGetKeyPtr(&tempDesc,
- keyOSASourceStart,
- typeWildCard,
- &actualType,
- start,
- sizeof(short),
- &actualSize);
-
- if (error != noErr)
- {
- error = errAECoercionFail;
- goto CleanUp;
- }
-
- error = AEGetKeyPtr(&tempDesc,
- keyOSASourceEnd,
- typeWildCard,
- &actualType,
- end,
- sizeof(short),
- &actualSize);
-
- if (error != noErr)
- {
- error = errAECoercionFail;
- goto CleanUp;
- }
-
- CleanUp:
-
- AEDisposeDesc(&tempDesc);
-
- return error;
- }
-
- //----------------------------------------------------------------------------------
- // Converts descriptor dataHandle to a Point
- //----------------------------------------------------------------------------------
-
- OSErr
- DescToPoint(const AEDesc* desc, Point* aPoint)
- {
- AEDesc tempDesc = {typeNull, nil};
- Handle dataHandle = nil;
-
- if (desc->descriptorType == typeQDPoint)
- {
- dataHandle = desc->dataHandle;
- }
- else
- {
- if (AECoerceDesc(desc, typeQDPoint, &tempDesc) == noErr)
- dataHandle = tempDesc.dataHandle;
- else
- return errAECoercionFail;
- }
-
- *aPoint = *(Point *)*dataHandle;
-
- AEDisposeDesc(&tempDesc);
-
- return(noErr);
- }
- //----------------------------------------------------------------------------------
- // Converts descriptor dataHandle to a pascal string
- //----------------------------------------------------------------------------------
-
- OSErr
- DescToPString(const AEDesc* desc, Str255 aPString, short maxLength)
- {
- AEDesc tempDesc = {typeNull, nil};
- Handle dataHandle = nil;
- long charCount;
-
- if (desc->descriptorType == typeChar)
- {
- dataHandle = desc->dataHandle;
- }
- else
- {
- if (AECoerceDesc(desc, typeChar, &tempDesc) == noErr)
- dataHandle = tempDesc.dataHandle;
- else
- return errAECoercionFail;
- }
-
- charCount = GetHandleSize(dataHandle);
-
- if (charCount > maxLength)
- {
- AEDisposeDesc(&tempDesc);
- return errAECoercionFail;
- }
-
- HLock(dataHandle);
- BlockMoveData(*dataHandle, &aPString[1], charCount);
- HUnlock(dataHandle);
-
- aPString[0] = charCount;
-
- AEDisposeDesc(&tempDesc);
-
- return(noErr);
- }
-
- //----------------------------------------------------------------------------------
- // Converts descriptor dataHandle to a Rectangle
- //----------------------------------------------------------------------------------
-
- OSErr
- DescToRect(const AEDesc* desc, Rect* aRect)
- {
- AEDesc tempDesc = {typeNull, nil};
- Handle dataHandle = nil;
-
- if (desc->descriptorType == typeRectangle)
- {
- dataHandle = desc->dataHandle;
- }
- else
- {
- if (AECoerceDesc(desc, typeQDRectangle, &tempDesc) == noErr)
- dataHandle = tempDesc.dataHandle;
- else
- return errAECoercionFail;
- }
-
- *aRect = *(Rect *)*dataHandle;
-
- AEDisposeDesc(&tempDesc);
-
- return(noErr);
- }
-
- //----------------------------------------------------------------------------------
- // Converts descriptor dataHandle to a RGBColor
- //----------------------------------------------------------------------------------
-
- OSErr
- DescToRGBColor(const AEDesc* desc, RGBColor* aRGBColor)
- {
- AEDesc tempDesc = {typeNull, nil};
- Handle dataHandle = nil;
-
- if (desc->descriptorType == typeRGBColor) // a color value
- {
- dataHandle = desc->dataHandle;
- }
- else {
- if (AECoerceDesc(desc, typeRGBColor, &tempDesc) == noErr)
- dataHandle = tempDesc.dataHandle;
- else
- return errAECoercionFail;
- }
-
- *aRGBColor = *(RGBColor *)*dataHandle;
-
- AEDisposeDesc(&tempDesc);
-
- return noErr;
- }
-
- //----------------------------------------------------------------------------------
- // Converts descriptor dataHandle to a short.
- //----------------------------------------------------------------------------------
-
- OSErr
- DescToShort(const AEDesc* desc, short* aShort)
- {
- AEDesc tempDesc = {typeNull, nil};
- Handle dataHandle = nil;
-
- if (desc->descriptorType == typeShortInteger)
- {
- dataHandle = desc->dataHandle;
- }
- else
- {
- if (AECoerceDesc(desc, typeShortInteger, &tempDesc) == noErr)
- dataHandle = tempDesc.dataHandle;
- else
- return errAECoercionFail;
- }
-
- *aShort = *(short *)*dataHandle;
-
- AEDisposeDesc(&tempDesc);
-
- return noErr;
- }
-
- //----------------------------------------------------------------------------------
- // Converts descriptor dataHandle to a short double
- //----------------------------------------------------------------------------------
-
- OSErr
- DescToShortDouble(const AEDesc* desc, short double* aShortDouble)
- {
- AEDesc tempDesc = {typeNull, nil};
- Handle dataHandle = nil;
-
- if (desc->descriptorType == typeFloat)
- {
- dataHandle = desc->dataHandle;
- }
- else
- {
- if (AECoerceDesc(desc, typeFloat, &tempDesc) == noErr)
- dataHandle = tempDesc.dataHandle;
- else
- return errAECoercionFail;
- }
-
- *aShortDouble = **(short double**)dataHandle;
-
- AEDisposeDesc(&tempDesc);
-
- return(noErr);
- }
-
- //----------------------------------------------------------------------------------
- // Copies descriptor dataHandle to another handle, if its text
- //----------------------------------------------------------------------------------
-
- OSErr
- DescToTextHandle(const AEDesc* desc, Handle *text)
- {
- AEDesc tempDesc = {typeNull, nil};
- Handle dataHandle = nil;
-
- if (desc->descriptorType == typeChar)
- {
- dataHandle = desc->dataHandle;
- }
- else
- {
- if (AECoerceDesc(desc, typeChar, &tempDesc) == noErr)
- dataHandle = tempDesc.dataHandle;
- else
- return errAECoercionFail;
- }
-
- HLock(dataHandle);
- HandToHand(&dataHandle);
- HUnlock(dataHandle);
-
- *text = dataHandle;
-
- AEDisposeDesc(&tempDesc);
-
- return(noErr);
- }
-
- #pragma mark -
- // ---------------------------------------------------------------------------
- // Token ADT
- // ---------------------------------------------------------------------------
- // The following set of utility routines extract the requested data element
- // from a CoreTokenRecord. This could be done with a bunch of ugly casts
- // sprinkled throughout the code, but these functins provide greater readability.
- // ---------------------------------------------------------------------------
- //
- // Here's our token data type, a handle to which is stored in the token.dataHandle:
- //
- // typedef struct CoreToken_TAG
- // {
- // DescType dispatchClass; // same as descriptorType, except for property tokens
- // Boolean usePropertyCode;
- // DescType propertyCode;
- // long documentNumber;
- // unsigned long elementNumber;
- // DescType elementType;
- // long beginOffset;
- // long endOffset;
- // AEDescList listOfObjects;
- // FSSpec fsSpec;
- // } CoreTokenRecord;
-
- // ---------------------------------------------------------------------------
-
- DescType
- ExtractDispatchClassFromToken(const AEDesc *token)
- {
-
- DescType dispatchClass = typeNull;
- CoreTokenHandle tokenData = (CoreTokenHandle)(token->dataHandle);
-
- if (tokenData != nil)
- dispatchClass = (**tokenData).dispatchClass;
-
- return dispatchClass;
-
- }
-
- // ---------------------------------------------------------------------------
-
- DescType
- ExtractObjectClassFromToken(const AEDesc *token)
- {
-
- DescType objectClass = typeNull;
- CoreTokenHandle tokenData = (CoreTokenHandle)(token->dataHandle);
-
- if (tokenData != nil)
- objectClass = (**tokenData).objectClass;
-
- return objectClass;
-
- }
-
- // ---------------------------------------------------------------------------
- // The field usePropertyCode has been removed from the token record,
- // so we emulate it here by seeing if the propertyCode field is typeNull,
- // which is interpreted to mean that this is NOT a property token
-
- Boolean
- ExtractUsePropertyCodeFromToken(const AEDesc *token)
- {
-
- Boolean usePropertyCode = false;
- CoreTokenHandle tokenData = (CoreTokenHandle)(token->dataHandle);
-
- if (tokenData != nil)
- usePropertyCode = ((**tokenData).propertyCode != typeNull);
-
- return usePropertyCode;
-
- }
-
- // ---------------------------------------------------------------------------
-
- DescType
- ExtractPropertyCodeFromToken(const AEDesc *token)
- {
-
- DescType propertyCode = typeNull;
- CoreTokenHandle tokenData = (CoreTokenHandle)(token->dataHandle);
-
- if (tokenData != nil)
- propertyCode = (**tokenData).propertyCode;
-
- return propertyCode;
-
- }
-
- // ---------------------------------------------------------------------------
-
- long
- ExtractDocumentNumberFromToken(const AEDesc *token)
- {
-
- long documentNumber = 0L;
- CoreTokenHandle tokenData = (CoreTokenHandle)(token->dataHandle);
-
- if (tokenData != nil)
- documentNumber = (**tokenData).documentNumber;
-
- return documentNumber;
-
- }
-
- // ---------------------------------------------------------------------------
-
- long
- ExtractElementNumberFromToken(const AEDesc *token)
- {
-
- long elementNumber = 0;
- CoreTokenHandle tokenData = (CoreTokenHandle)(token->dataHandle);
-
- if (tokenData != nil)
- elementNumber = (**tokenData).elementNumber;
-
- return elementNumber;
- }
-
- // ---------------------------------------------------------------------------
-
- WindowPtr
- ExtractWindowPtrFromToken(const AEDesc *token)
- {
- WindowPtr window = nil;
- CoreTokenHandle tokenData = (CoreTokenHandle)(token->dataHandle);
-
- if (tokenData != nil)
- window = (**tokenData).window;
-
- return window;
-
- }
-
- #pragma mark -
- // ---------------------------------------------------------------------------
-
- OSErr
- GetDocumentReferenceFromToken(const AEDesc *token, DocumentReference *document)
- {
- OSErr error = noErr;
-
- long documentNumber = ExtractDocumentNumberFromToken(token);
-
- error = GetDocumentByDocumentNumber(documentNumber, document);
-
- if (error != noErr || *document == nil)
- error = errAENoSuchObject;
-
- return error;
-
- }
-
- //----------------------------------------------------------------------------------
-
- OSErr
- GetElementReferenceFromToken(const AEDesc *token, ElementReference *element)
- {
- OSErr error = noErr;
- DocumentReference document = nil;
- unsigned long elementNumber = ExtractElementNumberFromToken(token);
-
- error = GetDocumentReferenceFromToken(token, &document);
-
- if (error == noErr)
- *element = GetElementByNumber(GetDocumentElementList(document), elementNumber);
-
-
- if (error != noErr || *element == nil)
- error = errAENoSuchObject;
-
- return error;
-
- }
-
- #pragma mark -
- // ----------------------------------------------------------------------------------------
- // Install the OSL callback routines defined below
- // ----------------------------------------------------------------------------------------
-
- Boolean
- InstallObjectCallbackFunctions(void)
- {
- OSErr error =
- AESetObjectCallbacks(
- NewOSLCompareProc (OSLCompareObjectsCallback),
- NewOSLCountProc (OSLCountObjectsCallback),
- (OSLDisposeTokenUPP) NULL,
- (OSLGetMarkTokenUPP) NULL,
- (OSLMarkUPP) NULL,
- (OSLAdjustMarksUPP) NULL,
- (OSLGetErrDescUPP) NULL);
-
- return (error == noErr);
- }
-
- // ----------------------------------------------------------------------------------------
- // Count the number of objects of the desiredType that are in the container
- //
- // For completeness, this function has the same structure as the container heirarchy
- // for the object model structure for the application.
- //
- // ----------------------------------------------------------------------------------------
-
- static pascal OSErr
- OSLCountObjectsCallback(DescType desiredType, // class of elements to count
- DescType containerClass, // container class ID
- const AEDesc *container, // token for container
- long *result) // the number we counted
- {
- OSErr error = noErr;
- DocumentReference document;
- ElementReference element;
- ElementList elementList;
-
- switch (containerClass)
- {
- case cApplication:
- case typeNull:
- switch (desiredType)
- {
- case cDocument:
- *result = CountDocuments(GetDocumentList());
- break;
-
- case cWindow:
- *result = CountWindows();
- break;
-
- default:
- error = errAECantHandleClass;
- break;
- }
- break;
-
- case cDocument:
- error = GetDocumentReferenceFromToken(container, &document);
- if (error != noErr)
- goto CleanUp;
-
- elementList = GetDocumentElementList(document);
- if (elementList == nil)
- {
- error = errAEEventNotHandled;
- goto CleanUp;
- }
-
- switch (desiredType)
- {
- case cGroupedGraphic:
- case cGraphicObject:
- case cGraphicLine:
- case cRectangle:
- case cRoundedRectangle:
- case cOval:
- case cPolygon:
- *result = CountElementsByClass(elementList, desiredType);
- break;
-
- default:
- error = errAECantHandleClass;
- }
- break;
-
- case cGroupedGraphic:
- error = GetDocumentReferenceFromToken(container, &document);
- if (error != noErr)
- goto CleanUp;
-
- error = GetElementReferenceFromToken(container, &element);
- if (error != noErr)
- goto CleanUp;
-
- elementList = GetSubElementList(element);
- if (elementList == nil)
- {
- error = errAEEventNotHandled;
- goto CleanUp;
- }
-
- switch (desiredType)
- {
- case cGroupedGraphic:
- case cGraphicObject:
- case cGraphicLine:
- case cRectangle:
- case cRoundedRectangle:
- case cOval:
- case cPolygon:
- *result = CountElementsByClass(elementList, desiredType);
- break;
-
- default:
- error = errAECantHandleClass;
- }
- break;
-
- default:
- error = errAECantHandleClass;
- break;
- }
-
- CleanUp:
-
- return error;
- }
-
- // ----------------------------------------------------------------------------------------
- // Perform testing against two objects -- used by OSL to resolve complex specifier tests
- // ----------------------------------------------------------------------------------------
-
- static pascal OSErr
- OSLCompareObjectsCallback (DescType comparisonOperator, // operator to use
- const AEDesc *object, // left-hand side
- const AEDesc *descriptorOrObject, // right-hand side
- Boolean *result)
- {
- OSErr error = noErr;
-
- AEDesc desc1 = {typeNull, NULL};
- AEDesc desc2 = {typeNull, NULL};
- AEDesc temp = {typeNull, NULL};
-
- // This first AEDesc is a token to a specific object, so we resolve it.
-
- error = ExtractData(object, &desc1);
- if (error != noErr)
- goto CleanUp;
-
- // A second AEDesc is either a token to another object or an AEDesc containing literal data.
-
- error = ExtractData(descriptorOrObject, &desc2);
- if (error != noErr)
- goto CleanUp;
-
- // Make sure the data type extracted from the second AEDesc is the same as the
- // data specified by the first AEDesc.
-
- // Create a temporary duplicate of desc2 and coerce it to the
- // requested type. This could call a coercion handler you have
- // installed. If there are no errors, stuff the coerced value back into desc2
-
- if (desc1.descriptorType != desc2.descriptorType)
- {
- error = AEDuplicateDesc(&desc2, &temp);
- if (error != noErr)
- goto CleanUp;
-
- error = AECoerceDesc(&temp, desc1.descriptorType, &desc2);
- if (error != noErr)
- goto CleanUp;
- }
-
- // Now that we know that the 2 types are the same, compare them
- // This has to handle all the data types used in the application's
- // object model implementation.
-
- switch(desc1.descriptorType)
- {
- case typeChar:
- error = OSLCompareText(comparisonOperator, &desc1, &desc2, result);
- break;
-
- case typeShortInteger: // also covers typeSMInt 'shor'
- case typeLongInteger: // also covers typeInteger 'long'
- case typeMagnitude: // 'magn'
- error = OSLCompareInteger(comparisonOperator, &desc1, &desc2, result);
- break;
-
- case typeEnumerated:
- error = OSLCompareEnumeration(comparisonOperator, &desc1, &desc2, result);
- break;
-
- case typeFixed:
- error = OSLCompareFixed(comparisonOperator, &desc1, &desc2, result);
- break;
-
- case typeFloat:
- error = OSLCompareFloat(comparisonOperator, &desc1, &desc2, result);
- break;
-
- case typeBoolean:
- error = OSLCompareBoolean(comparisonOperator, &desc1, &desc2, result);
- break;
-
- case typeRGBColor:
- error = OSLCompareRGBColor(comparisonOperator, &desc1, &desc2, result);
- break;
-
- case typeQDRectangle:
- error = OSLCompareRect(comparisonOperator, &desc1, &desc2, result);
- break;
-
- case typeQDPoint:
- error = OSLComparePoint(comparisonOperator, &desc1, &desc2, result);
- break;
-
- default:
- error = errAEWrongDataType;
- }
-
- CleanUp:
-
- AEDisposeDesc(&desc1);
- AEDisposeDesc(&desc2);
- AEDisposeDesc(&temp);
-
- return error;
- }
-
- #pragma mark -
- // ----------------------------------------------------------------------------------------
-
- static OSErr
- OSLCompareText(DescType oper, const AEDesc *desc1, const AEDesc *desc2, Boolean *result)
- {
- OSErr error = noErr;
-
- short compareResult;
- char *lhs;
- char *rhs;
- long lhsSize;
- long rhsSize;
-
- lhsSize = GetHandleSize(desc1->dataHandle);
- MoveHHi(desc1->dataHandle);
- HLock(desc1->dataHandle);
- lhs = *(desc1->dataHandle);
-
- rhsSize = GetHandleSize(desc2->dataHandle);
- MoveHHi(desc2->dataHandle);
- HLock(desc2->dataHandle);
- rhs = *(desc2->dataHandle);
-
- compareResult = CompareText(lhs, rhs, lhsSize, rhsSize, nil);
-
- switch (oper)
- {
- case kAEEquals:
- *result = (compareResult == 0);
- break;
-
- case kAELessThan:
- *result = (compareResult < 0);
- break;
-
- case kAELessThanEquals:
- *result = (compareResult <= 0);
- break;
-
- case kAEGreaterThan:
- *result = (compareResult > 0);
- break;
-
- case kAEGreaterThanEquals:
- *result = (compareResult >= 0);
- break;
-
- case kAEBeginsWith:
- if (rhsSize > lhsSize)
- {
- *result = false;
- }
- else
- {
- // compare only the number of characters in rhs
- // begin comparing at the beginning of lhs
- compareResult = CompareText(lhs, rhs, rhsSize, rhsSize, nil);
- *result = (compareResult == 0);
- }
- break;
-
- case kAEEndsWith:
- if (rhsSize > lhsSize)
- {
- *result = false;
- }
- else
- {
- // compare only the number of characters in rhs
- // begin comparing rhsSize characters from the end of lhs
- // start
-
- lhs += (lhsSize - rhsSize);
- compareResult = CompareText(lhs, rhs, rhsSize, rhsSize, nil);
- *result = (compareResult == 0);
- }
- break;
-
- case kAEContains:
- // Here I use an inefficient search strategy, but we're dealing with small amounts
- // of text and by using CompareText(), we're doing the same style of comparison
- // as in the other cases above.
-
- *result = false;
- while (lhsSize >= rhsSize)
- {
- compareResult = CompareText(lhs, rhs, rhsSize, rhsSize, nil);
- if (compareResult == 0)
- {
- *result = true;
- break;
- }
- lhs++;
- lhsSize--;
- }
- break;
-
- default:
- error = errAEBadTestKey;
- }
-
- return error;
- }
-
- // ----------------------------------------------------------------------------------------
-
- static OSErr
- OSLCompareEnumeration(DescType oper, const AEDesc *desc1, const AEDesc *desc2, Boolean *result)
- {
- OSErr error = noErr;
- long lhs;
- long rhs;
- AEDesc charDesc = {typeNull, nil};
-
- // Make each number is a long integer (in case it's a short integer or other integer type)
- // before extracting the data */
-
- error = AECoerceDesc(desc1, typeChar, &charDesc);
- if (error != noErr)
- goto CleanUp;
-
- lhs = **(long **)(charDesc.dataHandle);
- AEDisposeDesc(&charDesc);
-
- error = AECoerceDesc(desc2, typeChar, &charDesc);
- if (error != noErr)
- goto CleanUp;
-
- rhs = **(long **)charDesc.dataHandle;
- AEDisposeDesc(&charDesc);
-
- switch (oper)
- {
- case kAEEquals:
- *result = (lhs == rhs); // equality is the only test that makes sense for enumerators
- break;
-
- default:
- error = errAEBadTestKey;
- }
-
- CleanUp:
- AEDisposeDesc(&charDesc);
-
- return error;
- }
-
- // ----------------------------------------------------------------------------------------
-
- static OSErr
- OSLCompareInteger(DescType oper, const AEDesc *desc1, const AEDesc *desc2, Boolean *result)
- {
- OSErr error = noErr;
- long lhs;
- long rhs;
- AEDesc longDesc = {typeNull, nil};
-
- // Make each number is a long integer (in case it's a short integer or other integer type)
- // before extracting the data */
-
- error = AECoerceDesc(desc1, typeLongInteger, &longDesc);
- if (error != noErr)
- goto CleanUp;
-
- lhs = **(long **)(longDesc.dataHandle);
- AEDisposeDesc(&longDesc);
-
- error = AECoerceDesc(desc2, typeLongInteger, &longDesc);
- if (error != noErr)
- goto CleanUp;
-
- rhs = **(long **)longDesc.dataHandle;
- AEDisposeDesc(&longDesc);
-
- switch (oper)
- {
- case kAEEquals:
- *result = (lhs == rhs);
- break;
-
- case kAELessThan:
- *result = (lhs < rhs);
- break;
-
- case kAELessThanEquals:
- *result = (lhs <= rhs);
- break;
-
- case kAEGreaterThan:
- *result = (lhs > rhs);
- break;
-
- case kAEGreaterThanEquals:
- *result = (lhs >= rhs);
- break;
-
- default:
- error = errAEBadTestKey;
- }
-
- CleanUp:
- AEDisposeDesc(&longDesc);
-
- return error;
- }
-
- // ----------------------------------------------------------------------------------------
-
- static OSErr
- OSLCompareFixed(DescType oper, const AEDesc *desc1, const AEDesc *desc2, Boolean *result)
- {
- OSErr error = noErr;
-
- Fixed lhs;
- Fixed rhs;
-
- error = DescToFixed(desc1, &lhs);
- if (error != noErr)
- return error;
-
- error = DescToFixed(desc2, &rhs);
- if (error != noErr)
- return error;
-
- switch (oper)
- {
- case kAEEquals:
- *result = (lhs == rhs);
- break;
-
- case kAELessThan:
- *result = (lhs < rhs);
- break;
-
- case kAELessThanEquals:
- *result = (lhs <= rhs);
- break;
-
- case kAEGreaterThan:
- *result = (lhs > rhs);
- break;
-
- case kAEGreaterThanEquals:
- *result = (lhs >= rhs);
- break;
-
- default:
- error = errAEBadTestKey;
- }
-
- return error;
- }
-
- // ----------------------------------------------------------------------------------------
-
- static OSErr
- OSLCompareFloat(DescType oper, const AEDesc *desc1, const AEDesc *desc2, Boolean *result)
- {
- OSErr error = noErr;
-
- float lhs;
- float rhs;
-
- error = DescToFloat(desc1, &lhs);
- if (error != noErr)
- return error;
-
- error = DescToFloat(desc2, &rhs);
- if (error != noErr)
- return error;
-
- switch (oper)
- {
- case kAEEquals:
- *result = (lhs == rhs);
- break;
-
- case kAELessThan:
- *result = (lhs < rhs);
- break;
-
- case kAELessThanEquals:
- *result = (lhs <= rhs);
- break;
-
- case kAEGreaterThan:
- *result = (lhs > rhs);
- break;
-
- case kAEGreaterThanEquals:
- *result = (lhs >= rhs);
- break;
-
- default:
- error = errAEBadTestKey;
- }
-
- return error;
- }
-
- // ----------------------------------------------------------------------------------------
- // Apple events defines a boolean as a 1-byte value containing 1 for TRUE and 0 for FALSE
-
- static OSErr
- OSLCompareBoolean(DescType oper, const AEDesc *desc1, const AEDesc *desc2, Boolean *result)
- {
- OSErr err = noErr;
-
- Boolean bool1 = ((**(char **)desc1->dataHandle) != 0);
- Boolean bool2 = ((**(char **)desc2->dataHandle) != 0);
-
- if (oper == kAEEquals)
- *result = (bool1 == bool2);
- else
- err = errAEBadTestKey; // No other tests make sense
-
- return err;
- }
-
- // ----------------------------------------------------------------------------------------
-
- static OSErr
- OSLCompareRGBColor(DescType oper, const AEDesc *desc1, const AEDesc *desc2, Boolean *result)
- {
- OSErr error = noErr;
-
- RGBColor lhs;
- RGBColor rhs;
-
- error = DescToRGBColor(desc1, &lhs);
- if (error != noErr)
- return error;
-
- error = DescToRGBColor(desc2, &rhs);
- if (error != noErr)
- return error;
-
- if (oper == kAEEquals)
- *result = EqualRGB(lhs, rhs);
- else
- error = errAEBadTestKey; // No other tests make sense
-
- return error;
- }
-
- // ----------------------------------------------------------------------------------------
-
- static OSErr
- OSLComparePoint(DescType oper, const AEDesc *desc1, const AEDesc *desc2, Boolean *result)
- {
- OSErr error = noErr;
-
- Point lhs;
- Point rhs;
-
- error = DescToPoint(desc1, &lhs);
- if (error != noErr)
- return error;
-
- error = DescToPoint(desc2, &rhs);
- if (error != noErr)
- return error;
-
- switch (oper)
- {
- case kAEEquals:
- *result = (lhs.h = rhs.h && lhs.v == rhs.v);
- break;
-
- case kAELessThan:
- *result = (lhs.h < rhs.h && lhs.v < rhs.v);
- break;
-
- case kAELessThanEquals:
- *result = (lhs.h <= rhs.h && lhs.v <= rhs.v);
- break;
-
- case kAEGreaterThan:
- *result = (lhs.h > rhs.h && lhs.v > rhs.v);
- break;
-
- case kAEGreaterThanEquals:
- *result = (lhs.h >= rhs.h && lhs.v >= rhs.v);
- break;
-
- default:
- error = errAEBadTestKey; // No other tests make sense
- }
-
- return error;
- }
-
- // ----------------------------------------------------------------------------------------
-
- static OSErr
- OSLCompareRect(DescType oper, const AEDesc *desc1, const AEDesc *desc2, Boolean *result)
- {
- OSErr error = noErr;
-
- Rect lhs;
- Rect rhs;
-
- error = DescToRect(desc1, &lhs);
- if (error != noErr)
- return error;
-
- error = DescToRect(desc2, &rhs);
- if (error != noErr)
- return error;
-
- switch (oper)
- {
- // compare size AND location
- case kAEEquals:
- *result = ((lhs.top == rhs.top) && (lhs.left == rhs.left) && (lhs.bottom == rhs.bottom) && (lhs.right == rhs.right));
- break;
-
- // compare size only on the rest of the tests
- case kAELessThan:
- *result = (((lhs.bottom - lhs.top) < (rhs.bottom - rhs.top)) && ((lhs.right - lhs.left) < (lhs.right - rhs.left)));
- break;
-
- case kAELessThanEquals:
- *result = (((lhs.bottom - lhs.top) < (rhs.bottom - rhs.top)) && ((lhs.right - lhs.left) < (lhs.right - rhs.left)));
- break;
-
- case kAEGreaterThan:
- *result = (((lhs.bottom - lhs.top) < (rhs.bottom - rhs.top)) && ((lhs.right - lhs.left) < (lhs.right - rhs.left)));
- break;
-
- case kAEGreaterThanEquals:
- *result = (((lhs.bottom - lhs.top) < (rhs.bottom - rhs.top)) && ((lhs.right - lhs.left) < (lhs.right - rhs.left)));
- break;
-
- case kAEContains:
- // Note: two identical Rects contain each other, according to this test:
- *result = ((lhs.top <= rhs.top) && (lhs.left <= rhs.left) && (lhs.bottom >= rhs.bottom) && (lhs.right >= rhs.right));
- break;
-
- default:
- error = errAEBadTestKey; // No other tests make sense
- }
-
- return error;
- }
-
- #pragma mark -
- // -------------------------------------------------------------------------------------------
- //
- // ExtractKeyDataParameter
- //
- // Extract the keyData parameter data from an apple event
- // -------------------------------------------------------------------------------------------
-
- OSErr
- ExtractKeyDataParameter(const AppleEvent *appleEvent, AEDesc *data)
- {
- OSErr error = noErr;
- AEDesc keyData = {typeNull, nil};
-
- error = AEGetKeyDesc(appleEvent, keyAEData, typeWildCard, &keyData);
-
- if (error == noErr)
- error = ExtractData(&keyData, data);
-
- AEDisposeDesc(&keyData);
-
- return error;
- }
-
- // ----------------------------------------------------------------------------------------
- // ExtractData can receive several types of data:
- // Source Processing
- // -------------------- -----------------------------
- // an Object specifier call AEResolve() to get token, then handle below
- // a property token call public accessors to get raw data from token
- // a object token if it's not a property token, the token itself is returned
- // raw data just return it, it's already data!
- // ----------------------------------------------------------------------------------------
-
- OSErr
- ExtractData(const AEDesc *source, AEDesc *data)
- {
- OSErr error = noErr;
- AEDesc temp = {typeNull, nil};
- DescType dispatchClass;
-
- if ((source->descriptorType == typeNull) || (source->dataHandle == nil))
- {
- error = errAENoSuchObject;
- goto CleanUp;
- }
-
- // If it's an object specifier, resolve into a token
- // Otherwise, just copy it
-
- if (source->descriptorType == typeObjectSpecifier)
- {
- error = AEResolve(source, kAEIDoMinimum, &temp);
- }
- else
- {
- error = AEDuplicateDesc(source, &temp);
- }
- if (error != noErr)
- goto CleanUp;
-
- // Next, determine which object should handle it, if any.
- // If it's a property token, get the dispatch class.
- // Otherwise, just get the descriptorType.
-
- if (temp.descriptorType == typeProperty)
- {
- dispatchClass = ExtractDispatchClassFromToken(&temp);
- }
- else
- dispatchClass = temp.descriptorType;
-
- // If it's a property token, get the data it refers to,
- // otherwise duplicate it and return
-
- // EXPANSION NOTE: When you add a new class,
- // you must add it to this switch statement
-
- switch (dispatchClass)
- {
- case cApplication:
- error = errAEEventNotHandled;
- break;
-
- case cDocument:
- error = GetDataFromDocument(&temp, NULL, data);
- break;
-
- case cWindow:
- error = GetDataFromWindow(&temp, NULL, data);
- break;
-
- case cGraphicObject:
- error = GetDataFromGraphicObject(&temp, NULL, data);
- break;
-
- default: // This is raw data or an non-property token
- error = AEDuplicateDesc(&temp, data);
- break;
- }
-
- CleanUp:
-
- AEDisposeDesc(&temp);
-
- return error;
- }
-
- // -------------------------------------------------------------------------------------------
- //
- // ResolveObjectSpecifier
- //
- // Given an ospec, return a token
- // -------------------------------------------------------------------------------------------
-
- OSErr
- ResolveObjectSpecifier(const AEDesc *source, AEDesc *data)
- {
- OSErr error = noErr;
-
- if (source->descriptorType == typeObjectSpecifier)
- {
- error = AEResolve(source, kAEIDoMinimum, data);
- }
- else
- {
- Assert(kAssertAlways, "ResolveObjectSpecifier() received bad data.");
- error = errAENotAnObjSpec;
- }
-
- return error;
- }
-
- #pragma mark -
- // ----------------------------------------------------------------------------------------
- // Object Specifier Helpers
- //-----------------------------------------------------------------------------------------
-
- OSErr CreateElementOSpec(DocumentReference document, ElementReference element, AEDesc *ospec)
- {
-
- OSErr error = noErr;
-
- AEDesc documentOSpec = {typeNull, nil};
- AEDesc objectIndex = {typeNull, nil};
-
- long index = 0L;
-
- ElementType elementType;
- DescType objectClass;
-
- // First, get the ospec for the document
-
- error = CreateDocumentOSpec(document, &documentOSpec);
-
- // Now, get the index of the object
-
- if (error == noErr)
- {
- elementType = GetElementType(element);
-
- index = GetIndexForElementType(document, element, elementType);
- if (index == 0L)
- error = errAENoSuchObject;
- }
-
- if (error == noErr)
- error = AECreateDesc(typeLongInteger, (Ptr)&index, sizeof(index), &objectIndex);
-
- // Create the complete object specifier for the graphic object
-
- if (error == noErr)
- error = ConvertElementTypeToObjectClass(elementType, &objectClass);
-
- if (error == noErr)
- error = CreateObjSpecifier(objectClass, // desired class
- &documentOSpec, // container object
- formAbsolutePosition, // keyForm
- &objectIndex, // index of this object
- false, // dispose inputs?
- ospec); // resulting object specifier
-
- AEDisposeDesc(&documentOSpec);
- AEDisposeDesc(&objectIndex);
-
- return error;
- }
-
- //----------------------------------------------------------------------------------
-
- OSErr CreateElementUniqueIDOSpec(DocumentReference document, ElementReference element, AEDesc *ospec)
- {
-
- OSErr error = noErr;
-
- AEDesc documentOSpec = {typeNull, nil};
- AEDesc objectID = {typeNull, nil};
-
- long uniqueID = 0L;
-
- ElementType elementType;
- DescType objectClass;
-
- elementType = GetElementType(element);
- uniqueID = GetElementNumber(element);
-
- // First, get the ospec for the document
-
- error = CreateDocumentOSpec(document, &documentOSpec);
-
- if (error == noErr)
- {
- error = AECreateDesc(typeLongInteger, (Ptr)&uniqueID, sizeof(uniqueID), &objectID);
- }
-
- // Create the complete object specifier for the graphic object
-
- if (error == noErr)
- error = ConvertElementTypeToObjectClass(elementType, &objectClass);
-
- if (error == noErr)
- error = CreateObjSpecifier(objectClass, // desired class
- &documentOSpec, // container object
- formUniqueID, // keyForm
- &objectID, // index of this object
- false, // dispose inputs?
- ospec); // resulting object specifier
-
- AEDisposeDesc(&documentOSpec);
- AEDisposeDesc(&objectID);
-
- return error;
- }
-
- //----------------------------------------------------------------------------------
-
- OSErr CreateGraphicObjectOSpec(DocumentReference document, ElementReference element, AEDesc *ospec)
- {
-
- OSErr error = noErr;
-
- AEDesc documentOSpec = {typeNull, nil};
- AEDesc objectIndex = {typeNull, nil};
-
- long index = 0L;
-
- ElementType elementType;
- DescType objectClass;
-
- // First, get the ospec for the document
-
- error = CreateDocumentOSpec(document, &documentOSpec);
-
- // Now, get the index of the object
-
- if (error == noErr)
- {
- elementType = GetElementType(element);
-
- index = GetIndexForElementType(document, element, elementType);
- if (index == 0L)
- error = errAENoSuchObject;
- }
-
- if (error == noErr)
- error = AECreateDesc(typeLongInteger, (Ptr)&index, sizeof(index), &objectIndex);
-
- // Create the complete object specifier for the graphic object
-
- if (error == noErr)
- error = ConvertElementTypeToObjectClass(elementType, &objectClass);
-
- if (error == noErr)
- error = CreateObjSpecifier(objectClass, // desired class
- &documentOSpec, // container object
- formAbsolutePosition, // keyForm
- &objectIndex, // index of this object
- false, // dispose inputs?
- ospec); // resulting object specifier
-
- AEDisposeDesc(&documentOSpec);
- AEDisposeDesc(&objectIndex);
-
- return error;
- }
-
- //----------------------------------------------------------------------------------
-
- OSErr CreateGraphicGroupMemberOSpec(DocumentReference document, ElementReference element, ElementReference subElement, AEDesc *ospec)
- {
-
- OSErr error = noErr;
-
- AEDesc groupOSpec = {typeNull, nil};
- AEDesc objectIndex = {typeNull, nil};
-
- long index = 0L;
-
- ElementType elementType;
- DescType objectClass;
-
- // First, get the ospec for the graphic group object
-
- error = CreateGraphicObjectOSpec(document, element, &groupOSpec);
-
- // Now, get the index of the subelement object
-
- if (error == noErr)
- {
- elementType = GetElementType(subElement);
-
- index = GetIndexForSubElementType(document, element, subElement, elementType);
- if (index == 0L)
- error = errAENoSuchObject;
- }
-
- if (error == noErr)
- error = AECreateDesc(typeLongInteger, (Ptr)&index, sizeof(index), &objectIndex);
-
- // Create the complete object specifier for the graphic object
-
- if (error == noErr)
- error = ConvertElementTypeToObjectClass(elementType, &objectClass);
-
- if (error == noErr)
- error = CreateObjSpecifier(objectClass, // desired class
- &groupOSpec, // container object
- formAbsolutePosition, // keyForm
- &objectIndex, // index of this object
- false, // dispose inputs?
- ospec); // resulting object specifier
-
- AEDisposeDesc(&groupOSpec);
- AEDisposeDesc(&objectIndex);
-
- return error;
- }
-
- //----------------------------------------------------------------------------------
-
- OSErr CreateDocumentOSpec(DocumentReference document, AEDesc *ospec)
- {
-
- OSErr error;
-
- AEDesc appObj = {typeNull, nil};
- AEDesc docObj = {typeNull, nil};
-
- Str63 docName;
-
- // Create the reference to the document by name
-
- GetDocumentName(document, docName);
-
- error = AECreateDesc(typeChar, (Ptr)&docName[1], docName[0], &docObj);
-
- // Create the complete object specifier for document by name
-
- error = CreateObjSpecifier(cDocument, // desired class
- &appObj, // container object
- formName, // keyForm
- &docObj, // this object
- false, // dispose inputs?
- ospec); // resulting object specifier
-
- AEDisposeDesc(&docObj);
- AEDisposeDesc(&appObj);
-
- return error;
- }
-
-
- // ---------------------------------------------------------------------------
- // CreateRangeDescriptorOSpec
- // ---------------------------------------------------------------------------
-
- OSErr
- CreateRangeDescriptorOSpec(const AEDesc* container, DescType desiredClass, long index1, long index2, AEDesc *ospec)
- {
- OSErr error = noErr;
- OSErr ignoreError;
-
- Boolean isRange = (index2 > index1);
-
- AEDesc currentContainer = {typeNull, nil};
- AEDesc offset = {typeNull, nil};
- AEDesc startObject = {typeNull, nil};
- AEDesc stopObject = {typeNull, nil};
- AEDesc range = {typeNull, nil};
-
- Assert(index1 >= 1, "CreateRangeDescriptorOSpec() : index1 must be >= 1");
- Assert(index2 > index1, "CreateRangeDescriptorOSpec() : index2 must be > index1");
-
- // Current container
-
- error = AECreateDesc(typeCurrentContainer, nil, 0L, ¤tContainer);
-
- // start object
-
- if (error == noErr)
- error = CreateOffsetDescriptor(index1, &offset);
-
- if (error == noErr)
- error = CreateObjSpecifier(desiredClass, ¤tContainer, formAbsolutePosition, &offset, false, &startObject);
-
- ignoreError = AEDisposeDesc(&offset);
-
- // stop object
-
- if (error == noErr)
- error = CreateOffsetDescriptor(index2, &offset);
-
- if (error == noErr)
- error = CreateObjSpecifier(desiredClass, ¤tContainer, formAbsolutePosition, &offset, false, &stopObject);
-
- ignoreError = AEDisposeDesc(&offset);
-
- // Home, home on the range...
-
- if (error == noErr)
- error = CreateRangeDescriptor(&startObject, &stopObject, false, &range);
-
- ignoreError = AEDisposeDesc(&startObject);
- ignoreError = AEDisposeDesc(&stopObject);
-
- if (error == noErr)
- error = CreateObjSpecifier(desiredClass, (AEDesc *)container, formRange, &range, false, ospec);
-
- AEDisposeDesc(&range);
-
- return error;
- }
-
- #pragma mark -
- // ----------------------------------------------------------------------------------------
- // typeAEList helper functions
- //----------------------------------------------------------------------------------
-
- Boolean TokenContainsTokenList(AEDesc *token)
- {
- return (token->descriptorType == typeAEList);
- }
-
- // -------------------------------------------------------------------------------------------
- // Note: make sure the result descriptor is {typeNull, nil} when it is passed in to this
-
- OSErr GetFirstNonListToken(AEDesc *token, AEDesc *result)
- {
- OSErr error = noErr;
- AEDesc tempToken = {typeNull, nil};
- AEKeyword keyword;
- long numItems;
- long itemNum;
-
- if (result->descriptorType == typeNull)
- {
- if (TokenContainsTokenList(token) == false)
- {
- error = AEDuplicateDesc(token, result);
- }
- else
- {
- error = AECountItems(token, &numItems);
-
- for (itemNum = 1; itemNum <= numItems; itemNum++)
- {
- error = AEGetNthDesc((AEDescList *)token, itemNum, typeWildCard, &keyword, &tempToken);
- if (error != noErr)
- goto CleanUp;
-
- error = GetFirstNonListToken(&tempToken, result);
- if ((error != noErr) || (result->descriptorType != typeNull))
- break;
-
- AEDisposeDesc(&tempToken);
- }
- }
- }
-
- CleanUp:
- if (error != noErr)
- AEDisposeDesc(result);
-
- AEDisposeDesc(&tempToken);
-
- return error;
- }
-
- //----------------------------------------------------------------------------------
- // On entry, flatList must be a valid AEDescList, created with AECreateList function
- // flatList can be an empty list, however.
-
- OSErr FlattenAEList(AEDescList *deepList, AEDescList *flatList)
- {
- OSErr error = noErr;
- AEDesc item = {typeNull, nil};
- AEKeyword keyword;
- long itemNum;
- long numItems;
-
- error = AECountItems(deepList, &numItems);
- if (error != noErr)
- goto CleanUp;
-
- for (itemNum = 1; itemNum <= numItems; itemNum++)
- {
- error = AEGetNthDesc(deepList, itemNum, typeWildCard, &keyword, &item);
- if (error != noErr)
- goto CleanUp;
-
- if (item.descriptorType == typeAEList)
- error = FlattenAEList(&item, flatList);
- else
- error = AEPutDesc(flatList, 0L, &item);
-
- if (error != noErr)
- goto CleanUp;
-
- AEDisposeDesc(&item);
- }
-
- CleanUp:
- if (error != noErr)
- AEDisposeDesc(flatList);
-
- AEDisposeDesc(&item);
-
- return error;
- }
-
- /*****************************************************************************
- *
- * EqualRGB
- *
- * Returns true if the two RGB colors are equal
- *
- *****************************************************************************/
- Boolean EqualRGB(RGBColor colorA, RGBColor colorB)
- {
- return((colorA.red == colorB.red) && (colorA.green == colorB.green) && (colorA.blue == colorB.blue));
- }
-
- #pragma mark -
- //----------------------------------------------------------------------------------
- // color coercion helpers
- //----------------------------------------------------------------------------------
-
- Boolean
- GetColorRecordByName(char *name, ColorRecord *colorRecord)
- {
- Boolean foundIt = false;
- short index;
-
- *colorRecord = fgColorTable[0]; // initialize return value to black
-
- for (index = 0; index < fgNumColors; index++)
- {
- if (CStringEqual(fgColorTable[index].name, name, false))
- {
- *colorRecord = fgColorTable[index];
- foundIt = true;
- break;
- }
- }
-
- return foundIt;
- }
-
-
- //----------------------------------------------------------------------------------
-
- Boolean
- GetColorRecordByCode(DescType code, ColorRecord *colorRecord)
- {
- Boolean foundIt = false;
- short index;
-
- *colorRecord = fgColorTable[0]; // initialize return value to black
-
- for (index = 0; index < fgNumColors; index++)
- {
- if (fgColorTable[index].code == code)
- {
- *colorRecord = fgColorTable[index];
- foundIt = true;
- break;
- }
- }
-
- return foundIt;
- }
-
- //----------------------------------------------------------------------------------
-
- Boolean
- GetColorRecordByRGB(RGBColor rgbValue, ColorRecord *colorRecord)
- {
- Boolean foundIt = false;
- short index;
-
- *colorRecord = fgColorTable[0]; // initialize return value to black
-
- for (index = 0; index < fgNumColors; index++)
- {
- if (EqualRGB(rgbValue, fgColorTable[index].rgbValue))
- {
- *colorRecord = fgColorTable[index];
- foundIt = true;
- break;
- }
- }
-
- return foundIt;
- }
-
-
- #pragma mark -
- // ----------------------------------------------------------------------------------------
- // Coercion Handlers
- // ----------------------------------------------------------------------------------------
-
- Boolean
- InstallCoercionHandlers(void)
- {
- OSErr error;
-
- // color coercions
-
- error = AEInstallCoercionHandler( typeChar, // fromType
- typeRGBColor, // toType
- (AECoercionHandlerUPP) NewAECoerceDescProc(CoerceColorNameToRGBColor),
- 0, // handler refCon
- true, // fromTypeIsDesc
- false); // isSysHandler
-
- if (error == noErr)
- error = AEInstallCoercionHandler( typeRGBColor, // fromType
- typeChar, // "as text"
- (AECoercionHandlerUPP) NewAECoerceDescProc(CoerceRGBColorToColorName),
- 0, // handler refCon
- true, // fromTypeIsDesc
- false); // isSysHandler
-
- if (error == noErr)
- error = AEInstallCoercionHandler( typeRGBColor, // fromType
- typeIntlText, // "as string"
- (AECoercionHandlerUPP) NewAECoerceDescProc(CoerceRGBColorToColorName),
- 0, // handler refCon
- true, // fromTypeIsDesc
- false); // isSysHandler
-
- if (error == noErr)
- error = AEInstallCoercionHandler(typeType, // fromType
- typeRGBColor, // toType
- (AECoercionHandlerUPP) NewAECoerceDescProc(CoerceColorCodeToRGBColor),
- 0, // handler refCon
- true, // fromTypeIsDesc
- false); // isSysHandler
-
-
- if (error == noErr)
- error = AEInstallCoercionHandler(typeEnumeration, // fromType
- typeRGBColor, // toType
- (AECoercionHandlerUPP) NewAECoerceDescProc(CoerceColorCodeToRGBColor),
- 0, // handler refCon
- true, // fromTypeIsDesc
- false); // isSysHandler
-
-
- // type to enum, and enum to type
-
- if (error == noErr)
- error = AEInstallCoercionHandler(typeType, // fromType
- typeEnumeration, // toType
- (AECoercionHandlerUPP) NewAECoerceDescProc(CoerceTypeToEnumeration),
- 0, // handler refCon
- true, // fromTypeIsDesc
- false); // isSysHandler
-
-
- if (error == noErr)
- error = AEInstallCoercionHandler(typeEnumeration, // fromType
- typeType, // toType
- (AECoercionHandlerUPP) NewAECoerceDescProc(CoerceEnumerationToType),
- 0, // handler refCon
- true, // fromTypeIsDesc
- false); // isSysHandler
-
-
- return (error == noErr);
- }
-
- // ----------------------------------------------------------------------------------------
- // Coerce a color name to a RGB color value
-
- static pascal OSErr
- CoerceColorNameToRGBColor(const AEDesc *fromDesc, // fromDesc, the source AEDesc
- DescType toType, // toType, the type we want
- long handlerRefCon, // refCon
- AEDesc *result) // toDesc, the resulting AEDesc
- {
- #pragma unused (handlerRefCon)
-
- OSErr error = noErr;
- ColorRecord color;
-
- char colorName[80];
-
- result->descriptorType = typeNull;
- result->dataHandle = nil;
-
- if (fromDesc->descriptorType == typeChar) // a color name
- {
- TextToCString(fromDesc->dataHandle, colorName, 80);
- GetColorRecordByName(colorName, &color);
- error = AECreateDesc(typeRGBColor, &color.rgbValue, sizeof(RGBColor), result);
- }
-
- if (result->descriptorType != toType)
- error = errAECoercionFail;
-
- return error;
- }
-
- // ----------------------------------------------------------------------------------------
- // Coerce a color enumerator to a RGB color value
-
- static pascal OSErr
- CoerceColorCodeToRGBColor(const AEDesc *fromDesc, // fromDesc, the source AEDesc
- DescType toType, // toType, the type we want
- long handlerRefCon, // refCon
- AEDesc *result) // toDesc, the resulting AEDesc
- {
- #pragma unused (handlerRefCon)
-
- OSErr error = noErr;
- ColorRecord color;
-
- DescType code;
-
- result->descriptorType = typeNull;
- result->dataHandle = nil;
-
- if (fromDesc->descriptorType == typeType || fromDesc->descriptorType == typeEnumeration) // a color enumerator
- {
- error = DescToDescType((AEDesc *)fromDesc, &code);
- if (error == noErr)
- {
- GetColorRecordByCode(code, &color);
- error = AECreateDesc(typeRGBColor, &color.rgbValue, sizeof(RGBColor), result);
- }
- }
-
- if (result->descriptorType != toType)
- error = errAECoercionFail;
-
- return error;
- }
-
- // ----------------------------------------------------------------------------------------
- // Coerce an RGBCcolor to a color name, as string or as text
-
- typedef struct IText
- {
- ScriptCode theScriptCode;
- LangCode theLangCode;
- char *theText;
- } IText;
-
- static pascal OSErr
- CoerceRGBColorToColorName(const AEDesc *fromDesc, // fromDesc, the source AEDesc
- DescType toType, // toType, the type we want
- long handlerRefCon, // refCon
- AEDesc *result) // toDesc, the resulting AEDesc
- {
- #pragma unused (handlerRefCon)
-
- OSErr error = noErr;
- ColorRecord color;
- IText intlText;
-
- RGBColor rgb;
- Boolean foundIt;
-
- result->descriptorType = typeNull;
- result->dataHandle = nil;
-
- if (fromDesc->descriptorType == typeRGBColor)
- {
- error = DescToRGBColor((AEDesc *)fromDesc, &rgb);
- if (error == noErr)
- {
- foundIt = GetColorRecordByRGB(rgb, &color);
- if (foundIt)
- {
- if (toType == typeChar)
- error = AECreateDesc(typeChar, color.name, strlen(color.name), result);
- else if (toType == typeIntlText)
- {
- intlText.theScriptCode = 0;
- intlText.theLangCode = 0;
- intlText.theText = color.name;
-
- error = AECreateDesc(typeIntlText, &intlText, sizeof(IText), result);
- }
- }
- else
- {
- char name[80];
- sprintf(name, "%d,%d,%d", rgb.red, rgb.blue, rgb.green);
- error = AECreateDesc(typeChar, name, strlen(name), result);
- }
- }
- }
-
- if (result->descriptorType != toType)
- error = errAECoercionFail;
-
- return error;
- }
-
- // ----------------------------------------------------------------------------------------
- // Coerce a typeEnumeration to typeType
-
- static pascal OSErr
- CoerceEnumerationToType( const AEDesc *fromDesc, // fromDesc, the source AEDesc
- DescType toType, // toType, the type we want
- long handlerRefCon, // refCon
- AEDesc *result) // toDesc, the resulting AEDesc
- {
- #pragma unused (handlerRefCon)
-
- OSErr error = noErr;
- DescType type;
-
- result->descriptorType = typeNull;
- result->dataHandle = nil;
-
- if (fromDesc->descriptorType == typeEnumeration)
- {
- error = DescToDescType((AEDesc *)fromDesc, &type);
- if (error == noErr)
- error = AECreateDesc(typeType, &type, sizeof(DescType), result);
- }
-
- if (result->descriptorType != toType)
- error = errAECoercionFail;
-
- return error;
- }
-
- // ----------------------------------------------------------------------------------------
- // Coerce a typeEnumeration to typeType
-
- static pascal OSErr
- CoerceTypeToEnumeration( const AEDesc *fromDesc, // fromDesc, the source AEDesc
- DescType toType, // toType, the type we want
- long handlerRefCon, // refCon
- AEDesc *result) // toDesc, the resulting AEDesc
- {
- #pragma unused (handlerRefCon)
-
- OSErr error = noErr;
- DescType enumeration;
-
- result->descriptorType = typeNull;
- result->dataHandle = nil;
-
- if (fromDesc->descriptorType == typeType)
- {
- error = DescToDescType((AEDesc *)fromDesc, &enumeration);
- if (error == noErr)
- error = AECreateDesc(typeEnumeration, &enumeration, sizeof(DescType), result);
- }
-
- if (result->descriptorType != toType)
- error = errAECoercionFail;
-
- return error;
- }
-
- #pragma mark -
- //----------------------------------------------------------------------------------
- // Handles formAbsolutePosition resolution
-
- OSErr
- NormalizeAbsoluteIndex(const AEDesc *keyData, long *index, long maxIndex, Boolean *isAllItems)
- {
-
- OSErr error = noErr;
-
- *isAllItems = false; // set to true if we receive kAEAll constant
-
- // Extract the formAbsolutePosition data, either a integer or a literal constant
-
- switch (keyData->descriptorType)
- {
- case typeLongInteger: // positve or negative index
- if (DescToLong(keyData, index) != noErr)
- return errAECoercionFail;
- break;
-
- case typeAbsoluteOrdinal: // 'abso'
- if (DescToDescType((AEDesc*)keyData, (DescType*)index) != noErr)
- return errAECoercionFail;
- break;
-
- default:
- return errAEWrongDataType;
- break;
- }
-
- // convert literal to number, or negative index to positive index
-
- switch (*index)
- {
- case kAEFirst:
- *index = 1L;
- break;
-
- case kAEMiddle:
- *index = (maxIndex >> 1) + (maxIndex % 2);
- break;
-
- case kAELast:
- *index = maxIndex;
- break;
-
- case kAEAny:
- *index = (TickCount() % maxIndex) + 1;
- break;
-
- case kAEAll:
- *index = 1L;
- *isAllItems = true;
- break;
-
- default:
- if (*index < 0) // convert a negative index from end of list to a positive index from beginning of list
- {
- *index = maxIndex + *index + 1;
- }
- break;
- }
-
- // range-check the new index number
-
- if ((*index < 1) || (*index > maxIndex))
- {
- error = errAEIllegalIndex;
- }
-
- return error;
- }
-
- //----------------------------------------------------------------------------------
- // Handles formRange resolution of boundary objects
-
- OSErr
- ProcessFormRange(AEDesc *keyData, AEDesc *start, AEDesc *stop)
- {
- OSErr error = noErr;
- AEDesc rangeRecord = {typeNull, nil};
- AEDesc ospec = {typeNull, nil};
-
- // coerce the range record data into an AERecord
-
- error = AECoerceDesc(keyData, typeAERecord, &rangeRecord);
- if (error != noErr)
- goto CleanUp;
-
- // object specifier for first object in the range
-
- error = AEGetKeyDesc(&rangeRecord, keyAERangeStart, typeWildCard, &ospec);
- if (error == noErr && ospec.descriptorType == typeObjectSpecifier)
- error = AEResolve(&ospec, kAEIDoMinimum, start);
-
- if (error != noErr)
- goto CleanUp;
-
- AEDisposeDesc(&ospec);
-
- // object specifier for last object in the range
-
- error = AEGetKeyDesc(&rangeRecord, keyAERangeStop, typeWildCard, &ospec);
- if (error == noErr && ospec.descriptorType == typeObjectSpecifier)
- error = AEResolve(&ospec, kAEIDoMinimum, stop);
-
- CleanUp:
-
- AEDisposeDesc(&ospec);
- AEDisposeDesc(&rangeRecord);
-
- return error;
- }
-
- //----------------------------------------------------------------------------------
-
-
-